package com.yeziji.job.config.support.listener;

import cn.hutool.extra.spring.SpringUtil;
import com.yeziji.job.business.jobInfo.base.JobInfo;
import com.yeziji.job.business.jobLog.service.JobLogService;
import com.yeziji.job.common.JobContext;
import com.yeziji.job.common.base.JobContextInfo;
import com.yeziji.job.common.log.YzjJobLogger;
import com.yeziji.job.constant.JobConstants;
import com.yeziji.job.constant.JobStatusEnum;
import com.yeziji.utils.expansion.MessageFormat2;
import com.yeziji.utils.expansion.Str2;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.listeners.JobListenerSupport;

import java.util.Objects;

/**
 * 任务默认监听器
 *
 * @author hwy
 * @since 2024/06/28 14:34
 **/
public class JobDefaultListener extends JobListenerSupport {
    /**
     * 任务名称
     */
    private final String jobName;
    /**
     * 任务log服务
     */
    public static volatile JobLogService JOB_LOG_SERVICE;

    public JobDefaultListener(String jobName) {
        this.jobName = jobName;
    }

    @Override
    public String getName() {
        return Str2.isBlankElse(jobName, "default");
    }

    @Override
    public void jobWasExecuted(JobExecutionContext context, JobExecutionException jobException) {
        JobContextInfo jobContextInfo = JobContext.get();
        // 需要判断当前回调是否是当前任务
        if (jobContextInfo != null && jobContextInfo.getJobInfo() != null) {
            JobInfo jobInfo = jobContextInfo.getJobInfo();
            String groupName = jobInfo.getGroupName();
            if (!Objects.equals(this.getFlag(groupName, this.jobName), this.getFlag(groupName, jobInfo.getName()))) {
                return;
            }
        } else {
            // the notice is not belong to this job
            return;
        }

        // 执行任务回调, 到这里任务已经全部完成
        try {
            // 执行任务异常
            if (jobException != null) {
                // finally flag
                YzjJobLogger.info(">>> [{}] failed !!!", jobContextInfo.getFlag());
                // 保存执行日志
                jobContextInfo.setStatus(Trigger.TriggerState.ERROR);
                getJobLogService().saveByJobContextInfo(jobContextInfo);
                return;
            }
            // finally flag
            YzjJobLogger.info(">>> [{}] finally !!!", jobContextInfo.getFlag());
            // 保存执行日志
            Trigger.TriggerState triggerState = context.getScheduler().getTriggerState(context.getTrigger().getKey());
            // 判断任务是否在启用状态，如果在启用状态时返回的 state 是 blocked 其实是等待下一次执行(qurtz_fired_trigger 存在)
            // 暂停状态手动执行的情况下，qurtz 会处理 fired 这时候会正常返回 complete
            if (JobStatusEnum.isStart(jobContextInfo.getJobInfo().getStatus()) && Objects.equals(triggerState, Trigger.TriggerState.BLOCKED)) {
                triggerState = Trigger.TriggerState.COMPLETE;
            }
            jobContextInfo.setStatus(triggerState);
            getJobLogService().saveByJobContextInfo(jobContextInfo);
        } catch (SchedulerException e) {
            YzjJobLogger.error(">>> [{}] finally callback error: {}", jobContextInfo.getFlag(), e.getMessage());
        } finally {
            JobContext.unbind(jobContextInfo.getFlag());
        }
    }

    /**
     * 获取任务 flag
     *
     * @param groupName 任务组名
     * @param jobName   任务名
     * @return {@link String} 任务标识
     */
    private String getFlag(String groupName, String jobName) {
        return MessageFormat2.format(JobConstants.JOB_DEFAULT_FLAG, groupName, jobName);
    }

    /**
     * 获取 jobLogService
     *
     * @return {@link JobLogService}
     */
    public static JobLogService getJobLogService() {
        if (JOB_LOG_SERVICE == null) {
            synchronized (JobDefaultListener.class) {
                if (JOB_LOG_SERVICE == null) {
                    JOB_LOG_SERVICE = SpringUtil.getBean(JobLogService.class);
                }
            }
        }
        return JOB_LOG_SERVICE;
    }
}
